package home

import (
	"bufio"
	"fmt"
	"os"
	"time"
)

func file1() {

	check := func(e error) {
		if e != nil {
			panic(e)
		}
	}

	d1 := []byte("hello\ngo\n")
	err := os.WriteFile("../tmp/dat1", d1, 0644)
	check(err)
	// 对于更细粒度的写入，先打开一个文件。

	f, err := os.Create("../tmp/dat2")
	check(err)
	// 打开文件后，一个习惯性的操作是：立即使用 defer 调用文件的 Close。

	defer f.Close()
	// 您可以按期望的那样 Write 字节切片。

	d2 := []byte{115, 111, 109, 101, 10}
	n2, err := f.Write(d2)
	check(err)
	fmt.Printf("wrote %d bytes\n", n2)
	// WriteString 也是可用的。

	n3, err := f.WriteString("writes\n")
	check(err)
	fmt.Printf("wrote %d bytes\n", n3)
	// 调用 Sync 将缓冲区的数据写入硬盘。

	f.Sync()
	// 与我们前面看到的带缓冲的 Reader 一样，bufio 还提供了的带缓冲的 Writer。

	w := bufio.NewWriter(f)
	n4, err := w.WriteString("buffered\n")
	check(err)
	fmt.Printf("wrote %d bytes\n", n4)
	// 使用 Flush 来确保，已将所有的缓冲操作应用于底层 writer。

	w.Flush()
}

func ext1() {
	// 在这个例子中，假如我们执行一个外部调用，
	// 并在 2 秒后使用通道 c1 返回它的执行结果。

	c1 := make(chan string, 1)
	go func() {
		time.Sleep(2 * time.Second)
		c1 <- "result 1"
	}()

	// 这里是使用 select 实现一个超时操作。
	// res := <- c1 等待结果，<-time.After 等待超时（1秒钟）以后发送的值。
	// 由于 select 默认处理第一个已准备好的接收操作，
	// 因此如果操作耗时超过了允许的 1 秒的话，将会执行超时 case。

	select {
	case res := <-c1:
		fmt.Println(res)
	case <-time.After(1 * time.Second):
		fmt.Println("timeout 1")
	}

	// 如果我们允许一个长一点的超时时间：3 秒，
	// 就可以成功的从 c2 接收到值，并且打印出结果。

	c2 := make(chan string, 1)

	go func() {
		time.Sleep(2 * time.Second)
		c2 <- "result 2"
	}()

	select {
	case res := <-c2:
		fmt.Println(res)
	case <-time.After(3 * time.Second):
		fmt.Println("timeout 2")
	}
}

func forww(w, s, t int) func(fn func(...interface{}), args ...interface{}) {
	// fmt.Println("wst", w, s, t)
	if w == 0 {
		return func(fn func(...interface{}), args ...interface{}) {
			fn(args...)
		}
	}

	return func(fn func(...interface{}), args ...interface{}) {
		ForPP(s, t)(func(a ...interface{}) {
			if len(args) > 0 {
				// fmt.Println("a...", a, w, s, args)
				i := a[len(a)-1]
				j := args[len(args)-1]
				if i.(int) <= j.(int) {
					return
				}
			}
			forww(w-1, s+1, t)(fn, append(args, a...)...)
		})

	}
}

var lb, le, lv = 0, 7, 3

func ext2() {
	for i1 := lb; i1 <= le; i1++ {
		for i2 := i1 + 1; i2 <= le; i2++ {
			for i3 := i2 + 1; i3 <= le; i3++ {

				fmt.Print([3]int{i1, i2, i3})

			}
		}
	}
	fmt.Printf("\n=======================\n")
	var got [][]int
	Gcom(lv, lb, le, []int{}, &got)
	for _, c := range got {
		fmt.Print(c)
	}
	fmt.Printf("\n=======================\n")
	forww(lv, lb, le)(func(args ...interface{}) {
		fmt.Print(args)
	})
	fmt.Printf("\n=======================\n")

}
